package com.ericdm.callingandsmsstatistics;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.CallLog.Calls;
import android.telephony.PhoneStateListener;
import android.telephony.SmsMessage;
import android.telephony.TelephonyManager;

public class MyBroadcastReceiver extends BroadcastReceiver
{
	private static String callingNumber = null;
	boolean isIncomingCall = false;
	TelephonyManager telephony;
	CustomPhoneStateListener customPhoneListener;
	@SuppressLint("SimpleDateFormat")
	@Override
	public void onReceive(Context context, Intent intent)
	{
		// TODO Auto-generated method stub
		if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) 
		{
			Intent intent_ = new Intent(context, CallingAndSmsStatisticsService.class);
			context.startService(intent_);
		}
		
		if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED"))
		{
			SmsMessage msg = null;
			Bundle bundle = intent.getExtras();
			if (bundle != null) 
			{
				Object[] pdusObj = (Object[]) bundle.get("pdus");
				for (Object p : pdusObj)
				{
					msg = SmsMessage.createFromPdu((byte[]) p);
					Date date = new Date(msg.getTimestampMillis());
					SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
					SimpleDateFormat format_ = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
					String receiveTime = format.format(date);
					String receiveTime_ = format_.format(date);
					String senderNumber = msg.getOriginatingAddress();
					DatabaseOperator databaseOperator = new DatabaseOperator();
					databaseOperator.insertData(DatabaseOperator.DATA_TYPE_RECEVIED_SMS, "1", senderNumber, receiveTime, receiveTime_);
					String queryStartDateString = databaseOperator.QueryTimeStrat();
					String queryEndDateString = databaseOperator.QueryTimeEnd();
					String currentDateString =  receiveTime;
					if (currentDateString.compareToIgnoreCase(queryStartDateString) >= 0 && currentDateString.compareToIgnoreCase(queryEndDateString) <= 0)
					{
						int sumTime = (int) (databaseOperator.GetSumReceiveSMS() + 1);
						databaseOperator.insertSumReceiveSms(sumTime);
						int phoneSumtime = (int) (databaseOperator.getPhoneNumberRecevieSms(senderNumber) + 1);
						databaseOperator.setPhoneNumberReceiveSms(senderNumber, phoneSumtime);
					}
					return;
				}
			}
		}
		
		if (intent.getAction().equals("android.intent.action.PHONE_STATE") || intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL")) 
		{
			if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL))
			{
				callingNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
				MainActivity.isOutGoingCall = true;
			}
			else
			{
				TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Service.TELEPHONY_SERVICE);
				switch (telephonyManager.getCallState())
				{
				case TelephonyManager.CALL_STATE_RINGING:
					callingNumber = intent.getStringExtra("incoming_number");
					isIncomingCall = true;
					break;
				default:
					break;
				}
			}
			Bundle extras = intent.getExtras();
			if (extras != null)
			{
				telephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
				customPhoneListener = new CustomPhoneStateListener(context);
				telephony.listen(customPhoneListener, PhoneStateListener.LISTEN_CALL_STATE);
			}
		}
	}
	
	public class CustomPhoneStateListener extends PhoneStateListener
	{
		Context theContext = null;
		public CustomPhoneStateListener(Context context)
		{
			theContext = context;
		}
		@SuppressWarnings("finally")
		public void onCallStateChanged(int state, String incomingNumber)
		{
			switch (state)
			{
			case TelephonyManager.CALL_STATE_RINGING:
				break;
			case TelephonyManager.CALL_STATE_OFFHOOK:
				break;
			case TelephonyManager.CALL_STATE_IDLE:
				if (MainActivity.isOutGoingCall == true)
				{
					MainActivity.outGoingCallEnd = MainActivity.outGoingCallEnd + 1;
					if (MainActivity.outGoingCallEnd == 2)
					{
						MainActivity.outGoingCallEnd = 0;
						MainActivity.isOutGoingCall = false;
						int i = 0;
						while (true)
						{
							if (isTheTopActivity("com.android.contacts", theContext))
							{
								try
								{
									Thread.sleep(1500);
								}catch (InterruptedException e)
								{
									e.printStackTrace();
								}finally
								{
									break;
								}
							}
							try
							{
								Thread.sleep(1000);
								i++;
							}catch (InterruptedException e)
							{
								e.printStackTrace();
							}finally
							{
								if (i == 5)
								{
									break;
								}
							}
						}
						DatabaseOperator databaseOperator = new DatabaseOperator();
						databaseOperator.insertData(DatabaseOperator.DATA_TYPE_OUTGOING_CALL, callingTimeDuration(theContext)+"", callingNumber, callingDate(theContext), callingDate_(theContext));
						String queryStartDateString = databaseOperator.QueryTimeStrat();
						String queryEndDateString = databaseOperator.QueryTimeEnd();
						String currentDateString =  callingDate(theContext);
						if (currentDateString.compareToIgnoreCase(queryStartDateString) >= 0 && currentDateString.compareToIgnoreCase(queryEndDateString) <= 0)
						{
							int sumTime = (int) (databaseOperator.GetSumOutgoingCall() + callingTimeDuration(theContext));
							databaseOperator.insertSumOutgoingTime(sumTime);
							int phoneSumtime = (int) (databaseOperator.getPhoneNumberOutgoingCallTime(callingNumber) + callingTimeDuration(theContext));
							databaseOperator.setPhoneNumberOutgoingCallTime(callingNumber, phoneSumtime);
						}
					}
				}
				else // Incoming call
				{
					int i = 0;
					while (true)
					{
						if (isTheTopActivity("com.android.contacts", theContext))
						{
							try
							{
								Thread.sleep(1500);

							} catch (InterruptedException e)
							{
								e.printStackTrace();

							} finally
							{
								break;
							}
						}
						try
						{
							Thread.sleep(1000);
							i++;
						} catch (InterruptedException e)
						{
							e.printStackTrace();
						} finally
						{
							if (i == 5)
							{
								break;
							}
						}
					}
					DatabaseOperator databaseOperator = new DatabaseOperator();
					databaseOperator.insertData(DatabaseOperator.DATA_TYPE_INCOMIG_CALL, callingTimeDuration(theContext)+"", callingNumber, callingDate(theContext), callingDate_(theContext));
					String queryStartDateString = databaseOperator.QueryTimeStrat();
					String queryEndDateString = databaseOperator.QueryTimeEnd();
					String currentDateString =  callingDate(theContext);
					if (currentDateString.compareToIgnoreCase(queryStartDateString) >= 0 && currentDateString.compareToIgnoreCase(queryEndDateString) <= 0)
					{
						int sumTime = (int) (databaseOperator.GetSumIncomingCall() + callingTimeDuration(theContext));
						databaseOperator.insertSumIncomingTime(sumTime);
						int phoneSumtime = (int) (databaseOperator.getPhoneNumberIncmingCallTime(callingNumber) + callingTimeDuration(theContext));
						databaseOperator.setPhoneNumberIncmingCallTime(callingNumber, phoneSumtime);
					}
				}
				break;
			default:
				break;
			}
			super.onCallStateChanged(state, incomingNumber);
			telephony.listen(customPhoneListener, PhoneStateListener.LISTEN_NONE);
		}  //onCallStateChanged end
	}   //CustomPhoneStateListener end
	
	public static Boolean isTheTopActivity(String packageName, Context context)
	{
		ActivityManager mActivityManager;
		mActivityManager = (ActivityManager)context.getSystemService("activity");
		List<RunningTaskInfo> theActivity = mActivityManager.getRunningTasks(100);
		List<String> aryListTaskID = new ArrayList<String>();
		List<String> aryListTaskName = new ArrayList<String>();
		for (ActivityManager.RunningTaskInfo amTask : theActivity)
		{
			aryListTaskName.add(amTask.baseActivity.getClassName());
			aryListTaskID.add("" + amTask.id);
			ComponentName topActivity = mActivityManager.getRunningTasks(1).get(0).topActivity;
			String packagename = topActivity.getPackageName();
			if (packagename.equals(packagename))
			{
				return true;
			}
			else 
			{
				return false;
			}
		}
		return false;
	}
	
	public static long callingTimeDuration(Context context)
	{
		Cursor cursor = context.getContentResolver().query(Calls.CONTENT_URI, new String[] { Calls.DURATION, Calls.TYPE, Calls.DATE, Calls.NUMBER }, null, null, Calls.DEFAULT_SORT_ORDER);
		long duration = 0L;
		if (cursor.moveToFirst())
		{
			int type = cursor.getInt(cursor.getColumnIndex(Calls.TYPE));
			duration = cursor.getLong(cursor.getColumnIndex(Calls.DURATION));
			switch (type)
			{
			case Calls.INCOMING_TYPE:
				return duration;
			case Calls.OUTGOING_TYPE:
				return duration;
			default:
				break;
			}
		}
		return duration;
	}
	
	@SuppressLint("SimpleDateFormat")
	public static String callingDate(Context context)
	{
		Cursor cursor = context.getContentResolver().query(Calls.CONTENT_URI, new String[] { Calls.DURATION, Calls.TYPE, Calls.DATE, Calls.NUMBER }, null, null, Calls.DEFAULT_SORT_ORDER);
		if (cursor.moveToFirst())
		{
			SimpleDateFormat sfd = new SimpleDateFormat("yyyy-MM-dd");
			Date date = new Date(Long.parseLong(cursor.getString(cursor.getColumnIndexOrThrow(Calls.DATE))));
			String time = sfd.format(date);
			return time;
		}
		return "";
	}
	
	@SuppressLint("SimpleDateFormat")
	public static String callingDate_(Context context)
	{
		Cursor cursor = context.getContentResolver().query(Calls.CONTENT_URI, new String[] { Calls.DURATION, Calls.TYPE, Calls.DATE, Calls.NUMBER }, null, null, Calls.DEFAULT_SORT_ORDER);
		if (cursor.moveToFirst())
		{
			SimpleDateFormat sfd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			Date date = new Date(Long.parseLong(cursor.getString(cursor.getColumnIndexOrThrow(Calls.DATE))));
			String time = sfd.format(date);
			return time;
		}
		return "";
	}
}
